home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d7
/
jmodm308.arc
/
JMODEM_D.C
< prev
next >
Wrap
Text File
|
1991-01-02
|
8KB
|
135 lines
/****************************************************************************/
/* FILE JMODEM_D.C */
/* Created 11-JAN-1990 Richard B. Johnson */
/* 405 Broughton Drive */
/* Beverly, Massachusetts 01915 */
/* BBS (508) 922-3166 */
/* */
/* encode(); (Data compression routine ) */
/* decode(); (Data expansion routine ) */
/* calc_crc(); (CRC checking and setting ) */
/* */
/****************************************************************************/
#include <stdlib.h> /* For _rotl() */
#include "jmodem.h" /* JMODEM primatives */
/****************************************************************************/
/* Encode (compress) the input string. */
/* The routine looks for groups of identical characters and replaces them */
/* with the character 0xBB, a word denoting the number of characters to */
/* duplicate, followed by the character to duplicate. */
/* */
/****************************************************************************/
word encode(word len, /* Length of input string */
register byte *in_buffer, /* Pointer to input buffer */
register byte *out_buffer) /* Pointer to output buffer */
{
word *wrds; /* Used to address string */
word how_many=0; /* Character count */
word count=0; /* Output byte count */
word start; /* Starting count */
byte dupl; /* Character to replace */
start = len; /* Save starting length */
while (len) /* While bytes in buffer */
{
if ( (*in_buffer == 0xBB) /* If the sentinel byte */
|| (*in_buffer == *(in_buffer+1)) ) /* If two adjacent the same */
{
*out_buffer++ = 0xBB; /* Insert , bump pointer */
dupl = *in_buffer; /* Save duplicate character */
how_many = 0; /* Duplicate char count */
while ( (*in_buffer++ == dupl) /* Count duplicates */
&& (len) ) /* While bytes still left. */
{
how_many++; /* Identical characters */
len --; /* Don't move to (while) */
}
wrds = (word *)out_buffer; /* Address string pointer */
*wrds = how_many; /* Insert character count */
out_buffer++; /* Adjust pointer */
out_buffer++; /* (get past count) */
*out_buffer++ = dupl; /* The duplicate character */
count += 4; /* Adjust byte count */
in_buffer--; /* Non-duplicate character */
}
else
{
*out_buffer++ = *in_buffer++; /* Copy byte */
count++; /* Character count */
len--;
}
if ( count > start ) /* Check unwarranted growth */
return JM_MAX;
}
return count; /* New length */
}
/****************************************************************************/
/* Decode (expand) the encoded string. */
/* Routine checks for a sentinel byte, 0xBB, and if found, takes the */
/* following word as the number of identical bytes to add. The actual */
/* byte to add is located following the length-word. */
/* */
/****************************************************************************/
word decode(word len, /* Length to input string */
register byte *in_buffer, /* Pointer to input buffer */
register byte *out_buffer) /* Pointer to output buffer */
{
byte *start; /* To save buffer start */
word *wrds; /* Address string as word */
if (len > DAT_MAX) /* Check for valid data */
return 0;
start = out_buffer; /* Save starting address */
while (len--)
{
if (*in_buffer == 0xBB ) /* If the sentinel byte */
{
wrds =(word *) ++in_buffer; /* Next character */
in_buffer++; /* Adjust buffer pointer */
in_buffer++; /* (get past the count) */
do /* Expand the byte */
{
*out_buffer++ = *in_buffer; /* Expand byte */
} while (--(*wrds) );
in_buffer++; /* Adjust pointer */
len -=3; /* Adjust input count */
}
else /* Else, just copy */
*out_buffer++ = *in_buffer++;
}
return (word) (out_buffer - start); /* New string length */
}
/****************************************************************************/
/* Calculate the simple JMODEM CRC */
/* Routine obtains a pointer to the buffer of characters to be checked. */
/* The first passed parameter is the length of the buffer. The CRC is */
/* returned. */
/* */
/****************************************************************************/
word calc_crc(word command, /* Set or Check CRC */
word length, /* Buffer length */
register byte *buffer) /* Pointer to the buffer */
{
register word *wrds; /* Address string as word */
word crc=0; /* Start at zero */
if (length <3) /* Check forvalid string */
return JM_MAX; /* Nothing to CRC */
length -=2; /* Don't CRC the CRC */
do
{
crc += (word) *buffer++; /* Sum first */
crc = _rotl(crc, (length & 0x07) ); /* Rotate max 7 bits left */
} while (--length);
wrds = (word *) buffer; /* Set up to point to CRC */
if (command == GET_CRC)
return (crc - *wrds); /* Return 0 if CRC okay */
else /* Else command = SET_CRC */
*wrds = crc; /* Set the CRC in string */
return crc; /* Return the CRC also */
}
/****************************************************************************/
/************************ E N D O F M O D U L E **************************/